#include<stdio.h>

int main(void) {
	//这次我们专门介绍一下字符串和读取的一些方式，先不涉及指针 
	//首先补充一下数组定义的一个小细节
	//给全部元素赋值，那么在数组定义时可以不给出数组的长度。例如：
	int a[] = { 0,2,4,6,8 };//这其实就是int a[5] = { 0,2,4,6,8 }，只不过你可以让编译器自己去算这个5
	char word[] = { 'H', 'e', 'l', 'l', 'o', '!' };//同理

	//字符串的特点
	//首先，最特殊的一点，字符串的结尾是'\0'也就是0，但不是‘0’，这个是终止标志
	//创建字符串，C语言中用字符数组，C++中有更好用的string，以后再学
	char s[] = "hello world!";//注意要用双引号！！这里会自动转换成一个字符数组，应该能理解，这个字符数组的最后一个元素是'\0',编译器会自动帮你加上
	//更多细节以后遇到之后上网搜搜都有，我不可能介绍细致到每一个小点

	//字符串的读入
	//第一种方法，scanf，这种读取方法从第一个非空白字符开始，遇到空格和换行符就认为当前字符串结束了，所以无法读取含有空格的字符串。
	char str1[50];
	scanf("%s", str1);//这里要注意，数组名本身就是地址（后面讲指针的时候会说到），所以不要加地址符号&
	printf("str1:%s", str1);
	//第二种方法，gets，这种读取方法遇到换行符才认为当前字符串结束，可以读取含有空格的字符串
	//这一般用于读取一整行的字符串，它会把最后的换行符读入，换成字符串的终止符号'\0'
	//如果一行中既输入了一个字符串，又输入了一个表示其他量的整数，就不能用gets了
	char str2[50];
	gets(str2);
	printf("str2:%s", str2);

	//看到这里先将上面的代码复制一份自己运行一下，你会发现一些问题




	//下面我们从比较底层的原理角度解释下为什么你在输入中打一个字符串之后按回车就会导致str2为空
	//之前我们使用scanf读取数(整数 浮点数 bool数)的时候不用管空格 换行，因为scanf读取数的时候会自动忽略掉这些东西
	//但在读取字符的时候不会，空格，换行也是字符，也能使用scanf("%c",&ch)读入
	//并且scanf在读取数或者字符串的时候最后遇到空格或者换行停止之后，这个空格或者换行还在缓冲区(可以了解下这个概念)
	//你下一次读取东西的时候，如果读取数字，无所谓，它会自动忽略这些东西，但是如果读取字符或者字符串，它就会把这个空白字符读进去
	//就举上面的例子， 输入abc然后回车，其实就是输入了abc\n，scanf先读取abc，遇到\n，停止了，str1就是abc'\0'
	//接下来轮到gets读取了，它首先读取的就是留在缓冲区的\n，按照gets的读取规则，遇到\n就停止，把\n读入，把它换成'\0'，所以str2就是'\0'，输出出来就是空字符串

	//可以自己试一下，输入abc空格edf，然后再回车，这个时候就正常了

	//那么怎么解决这个问题呢，给三种方法： 
	//第一种，先用gets，再用scanf(想想为什么可以)，如果后面再用一个gets还行不行呢？(不行的，为什么？)
	//第二种，全用gets——一般来说读一堆字符串我们都这么做
	//第三种，清空缓冲区（重点）
	//下面介绍一个函数getchar()，它的作用就是读取一个字符，并返回这个字符
	//第一种用法：清空缓冲区，我们刚刚是因为缓冲区里面有个\n，影响到了gets正常工作，那我们把\n读取，让它从缓冲区消失就好了
	char str3[50];
	scanf("%s", str3);
	printf("str3:%s", str3);

	getchar();

	char str4[50];
	gets(str4);
	printf("str4:%s", str4);

	//第二种用法：结合while，逐个读入字符
	char x;
	while ((x = getchar()) != ' ') {};
	while ((x = getchar()) != '\n') {};//看情况使用
	//原理就是读入一个字符进入x，再判断x是不是空格或者换行符，如果是的话就停止不读了
	//这种操作也是没有缓冲区残留的问题的
	//这里要注意，运算符是有优先级的，赋值运算符=的优先级是低于判断运算符！=的，所以前面要加括号
	//否则就会变成c和True or False比较
	//如果用这种方式读入一个字符数组，它的最后是不会自动加'\0'的，区分下字符数组和字符串，不完全等价

	//字符串的输出
	//一种就是printf了，很简单
	//另一种是puts，操作很简单，它有个特点就是会帮你自动换行，就是等价于printf("%s\n",str);
	puts(str4);
	return 0;
}